package cn.edu.fzu.homemaking.exception;

import java.io.EOFException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.TypeMismatchException;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import cn.edu.fzu.homemaking.web.Result;
import cn.edu.fzu.homemaking.web.RetCode;

/**
 * 异常处理：打印日志，匹配错误码
 */
@ControllerAdvice
public class GlobalExceptionHandler {

    private static final Logger log                 = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    private static final Result NULL_POINTER_RESULT = new Result(RetCode.OTHER_ERROR, "null pointer");

    private static final String ERR_499             = "499: null";

    @ExceptionHandler(ServiceException.class)
    @ResponseBody
    public Result bizExceptionHandler(ServiceException e) {
        // 通常 BizException 是业务主动抛出的(例如参数格式不正确，签名校验不成功等)，不需要打印异常堆栈
        log.warn(e.getMessage());
        return new Result(e.getCode(), e.getMessage());
    }


    @ExceptionHandler(IllegalArgumentException.class)
    @ResponseBody
    public Result illegalArgumentExceptionHandler(IllegalArgumentException e) {
        // 参数不正确
        log.warn(e.getMessage());
        return new Result(RetCode.PARAMETER_ERROR, e.getMessage());
    }


    @ExceptionHandler(RedirectException.class)
    @ResponseBody
    public Result bizExceptionHandler(RedirectException e) {
        // 重定向异常
        return new Result(e.getCode(), null, null, e.getMessage());
    }


    @ExceptionHandler({ TypeMismatchException.class })
    @ResponseBody
    public Result parameterException(Exception e) {
        log.warn(e.getMessage());
        return new Result(RetCode.PARAMETER_ERROR, e.getMessage());
    }


    @ExceptionHandler(HttpMessageNotReadableException.class)
    @ResponseBody
    public Result requestException(Exception e) {
        log.warn(e.getMessage());
        return new Result(RetCode.BAD_REQUEST);
    }


    @ExceptionHandler(NullPointerException.class)
    @ResponseBody
    public Result nullPointerException(Exception e) {
        log.error(e.getMessage(), e);
        return NULL_POINTER_RESULT;
    }


    @ExceptionHandler(EOFException.class)
    public void eofException() {
        // 客户端断开了连接, 此时已没有必要再输出任何响应
        log.error(ERR_499);
    }


    @ExceptionHandler(Exception.class)
    @ResponseBody
    public Result exception(Exception e) {
        log.error(e.getMessage(), e);
        return new Result(RetCode.OTHER_ERROR, e.getMessage());
    }

}
